<?php

/**
 * Created by PhpStorm.
 * User: 4399-0661
 * Date: 15-5-29
 * Time: 下午2:27
 */
class LibHttps extends \LibBase
{

    const  TYPE_INT = 'int';
    const TYPE_STRING = 'string';

    private $_errno = 0;
    private $_error = "";
    private $_result = '';
    private $_info = '';

    /**
     * 获取GET方法提交的数据
     * @param $key
     * @param string $type
     * @return mixed
     */
    public function get($key, $type = self::TYPE_INT)
    {
        return $this->_request($_GET, $key, $type);
    }

    /**
     * 获取POST方法提交的数据
     * @param $key
     * @param string $type
     * @return mixed
     */
    public function post($key, $type = self::TYPE_STRING)
    {
        return $this->_request($_POST, $key, $type);
    }

    /**
     * 获取上传的文件数据
     * @param null $name
     * @return null
     */
    public function file($name = NULL)
    {
        if ($name === null) return $_FILES;
        return isset($_FILES[$name]) ? $_FILES[$name] : null;
    }


    private function _request($datas, $key, $type)
    {
        if (isset($datas[$key])) {
            $data = $datas[$key];
        } else {
            $data = null;
        }
        !$type && $type = self::TYPE_INT;
        $method = '_filter' . ucfirst($type);
        return call_user_func_array([$this, $method], [$data]);
    }

    /**
     * 接收int型数据的处理
     * @param $data
     * @return int
     */
    private function _filterInt($data = "")
    {
        if (is_null($data) || !is_numeric($data)) return 0;
        return intval($data);
    }

    /**
     * 接收string型数据的处理
     * @param $data
     * @return string
     */
    private function _filterString($data = "")
    {
        if (is_null($data)) return "";
        if (get_magic_quotes_gpc()) {
            $data = stripslashes($data);
        }
        return trim($data);
    }


    /**
     * 模拟post请求
     * @param $url
     * @param null $data
     * @param null $connectTimeout
     * @param null $timeout
     * @param null $userAgent
     * @param null $cookie
     * @param null $nobody
     * @param bool $hasHeader
     * @return string
     */
    public
    function curlPost($url, $data = NULL, $connectTimeout = NULL, $timeout = NULL, $userAgent = NULL, $cookie = NULL, $nobody = NULL, $hasHeader = false)
    {
        $this->_curl('POST', $url, $data, $userAgent, $timeout, $connectTimeout, $cookie, $nobody, $hasHeader);
        if (!$this->_errno) {
            return $this->result();
        } else {
            $error = $this->errno() . ":" . $this->error();
            \LibLog::custom($error);
            return $error;
        }
    }

    /**
     * 模拟get请求
     * @param $url
     * @param null $data
     * @param null $connectTimeout
     * @param null $timeout
     * @param null $userAgent
     * @param null $cookie
     * @param null $nobody
     * @param bool $hasHeader
     * @return string
     */
    public
    function curlGet($url, $data = NULL, $connectTimeout = NULL, $timeout = NULL, $userAgent = NULL, $cookie = NULL, $nobody = NULL, $hasHeader = false)
    {
        $this->_curl('GET', $url, $data, $userAgent, $timeout, $connectTimeout, $cookie, $nobody, $hasHeader);
        if (!$this->_errno) {
            return $this->result();
        } else {
            $error = $this->errno() . ":" . $this->error();
            \LibLog::custom($error);
            return $error;
        }
     }
     
    /****************************************************
     *        微信提交API方法，返回微信指定JSON
     ****************************************************/

    public function wxHttpsRequest($url,$data = null){
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
            if (!empty($data)){
                    curl_setopt($curl, CURLOPT_POST, 1);
                    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $output = curl_exec($curl);
            curl_close($curl);
            return $output;
    }
     
    /**
     * 	作用：以post方式提交xml到对应的接口url
     */
    public 
    function postXmlCurl($xml,$url,$second=30)
    {
            //初始化curl
            $ch = curl_init();
            $header[] = "Content-type: text/xml";//定义content-type为xml
            //设置超时
            curl_setopt($ch, CURLOPT_TIMEOUT, $second);
            //这里设置代理，如果有的话
            //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
            //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
            curl_setopt($ch,CURLOPT_URL, $url);
            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
            curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
            //设置header
            curl_setopt($ch, CURLOPT_HEADER, FALSE);
            //要求结果为字符串且输出到屏幕上
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);//定义请求类型
            //post提交方式
            curl_setopt($ch, CURLOPT_POST, TRUE);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
            //运行curl
            $data = curl_exec($ch);
            curl_close($ch);
            //返回结果
            if($data)
            {
                    return $data;
            }
            else 
            { 
                    $error = curl_errno($ch);
                    echo "curl出错，错误码:$error"."<br>"; 
                    echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
                    curl_close($ch);
                    return false;
            }
    }

    /**
     * 	作用：使用证书，以post方式提交xml到对应的接口url
     */
    public 
    function postXmlSSLCurl($xml,$url,$second=30)
    {
            //初始化curl
            $ch = curl_init();
            $header[] = "Content-type: text/xml";//定义content-type为xml
            //超时时间
            curl_setopt($ch,CURLOPT_TIMEOUT,$second);
            //这里设置代理，如果有的话
            //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
            //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
            curl_setopt($ch,CURLOPT_URL, $url);
            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
            curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
            //设置header
            curl_setopt($ch,CURLOPT_HEADER,FALSE);
            //要求结果为字符串且输出到屏幕上
            curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
            //设置证书
            //使用证书：cert 与 key 分别属于两个.pem文件
            //默认格式为PEM，可以注释
            curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
            curl_setopt($ch,CURLOPT_SSLCERT, WxPayConfig::SSLCERT_PATH);
            //默认格式为PEM，可以注释
            curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
            curl_setopt($ch,CURLOPT_SSLKEY, WxPayConfig::SSLKEY_PATH);
            curl_setopt($ch,CURLOPT_CAINFO,'PEM');
            curl_setopt($ch,CURLOPT_CAINFO, WxPayConfig::ROOTCA_PATH); 
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);//定义请求类型
            //post提交方式
            curl_setopt($ch,CURLOPT_POST, true);
            curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
            $data = curl_exec($ch);
            //返回结果
            if($data){
                    curl_close($ch);
                    return $data;
            }
            else { 
                    $error = curl_errno($ch);
                    echo "curl出错，错误码:$error"."<br>"; 
                    echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
                    curl_close($ch);
                    return false;
            }
    }

    public
    function result()
    {
        return $this->_result;
    }

    public
    function errno()
    {
        return $this->_errno;
    }

    public
    function error()
    {
        return $this->_error;
    }

    /**
     * curl模拟请求
     * @param $method
     * @param $url
     * @param null $data
     * @param null $userAgent
     * @param null $timeout
     * @param null $connectTimeout
     * @param null $cookie
     * @param null $nobody
     * @param bool $hasHeader
     * @return int
     */
    private
    function _curl($method, $url, $data = NULL, $userAgent = NULL, $timeout = NULL, $connectTimeout = NULL, $cookie = NULL, $nobody = NULL, $hasHeader = false)
    {
        if (!function_exists('curl_init')) {
            $this->_errno = 900;
            $this->_error = 'Curl extents not install';
            return $this->_errno;
        }
        $headers = [
            'Accept-Language: zh-cn',
            'Connection: Keep-Alive',
            'Cache-Control: no-cache'
        ];

        $options = [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_USERAGENT => $userAgent,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false

        ];
        if ($method == 'POST') {
            $options[CURLOPT_POST] = 1;
            $data = $this->_buildQuery($data);
            if ($data) {
                $options[CURLOPT_POSTFIELDS] = $data;
            }
        } else {
            $options[CURLOPT_POST] = 0;
            if ($data) {
                if (is_array($data)) {
                    $data = $this->_buildQuery($data);
                }
                $url .= (strpos($url, "?") > 0 ? "&" : "?") . $data;
            }
        }
        $options[CURLOPT_URL] = $url;
        if ($nobody) {
            $options[CURLOPT_NOBODY] = true;
        }
        if ($hasHeader) {
            $options[CURLOPT_HEADER] = true;
        }
        if ($timeout > 0) {
            $options[CURLOPT_TIMEOUT] = $timeout;
        }
        if ($connectTimeout > 0) {
            $options[CURLOPT_CONNECTTIMEOUT] = $connectTimeout;
        }
        if ($cookie) {
            $options[CURLOPT_COOKIE] = $cookie;
        }
        $ch = curl_init();
        curl_setopt_array($ch, $options);
        $this->_result = curl_exec($ch);
        $this->_errno = curl_errno($ch);
        $this->_error = curl_error($ch);
        $this->_info = curl_getinfo($ch);
        curl_close($ch);
        $this->_error;
    }


    private
    function _buildQuery($data)
    {
        if (!is_array($data)) {
            return $data;
        }
        $data = $this->_makeParams($data);
        return implode('&', $data);
    }


    private
    function _makeParams($datas, $params = [])
    {
        foreach ($datas as $key => $value) {
            if (is_array($value)) {
                $params = $this->_makeParams($datas, $params);
            } else {
                $value = urlencode($value);
                $params[] = "{$key}=" . $value;
            }
        }
        return $params;
    }
} 